# 书籍系统模型管理（所有模型都写在这里）
# 注意：
# 1、数据库表之间存在依赖关系的，被依赖的模型得先加载，写在最前面
# 2、如果数据库模型不在同一个 .py文件中，在使用模型查询数据库即 model.query时，
#    被依赖的模型也要导入到视图函数(接口)所在文件，否则会报错

# 3、db.relationship()说明：
#    参数一：当前模型要关联(映射)到哪个模型，使用python的模型名，即class名称，字符串
#    参数 back_populates ：指定双向关系，两个模型中相互指定
#    参数 primaryjoin='BookType.type_id==book_info.type_id'指定外键关联字段

# 4、外键定义：db.ForeignKey('book_type.type_id') 指定当前模型中定义的关联模型名.外键字段


import json
from datetime import datetime
from exts import db


class BookTypeModel(db.Model):
    __tablename__ = 'book_type'
    type_id = db.Column(db.BigInteger, primary_key=True, autoincrement=True)
    type_code = db.Column(db.String(255), nullable=False, default='')
    type_name = db.Column(db.String(255), nullable=False, default='')

    def __repr__(self):
        return f"<BookTypeModel {self.type_name}>"


class FileInfoModel(db.Model):
    __tablename__ = 'file_info'
    file_id = db.Column(db.BigInteger, primary_key=True, autoincrement=True)
    file_name = db.Column(db.String(255), nullable=False)
    file_url = db.Column(db.String(255), nullable=False)
    file_type = db.Column(db.String(255), nullable=False)

    books = db.relationship('BookInfoModel', back_populates='file_info')


class BookInfoModel(db.Model):
    __tablename__ = 'book_info'
    id = db.Column(db.BigInteger, primary_key=True, autoincrement=True)
    book_no = db.Column(db.String(255), nullable=False, default='')
    book_no.__doc__ = '书籍编号'
    book_name = db.Column(db.String(255), nullable=False, default='')
    book_author = db.Column(db.String(255), nullable=False, default='')
    # 使用 表名.列名
    type_id = db.Column(db.BigInteger, db.ForeignKey('book_type.type_id'), nullable=False)  # 书籍类型id
    file_id = db.Column(db.BigInteger, db.ForeignKey('file_info.file_id'), nullable=False)  # 书籍封面图片地址id
    create_date = db.Column(db.DateTime, nullable=False, default=datetime.now)
    create_user = db.Column(db.String(255), nullable=False, default='')
    update_date = db.Column(db.DateTime, nullable=False, default=datetime.now)
    update_user = db.Column(db.String(255), nullable=False, default='')
    version = db.Column(db.Integer, nullable=False, default=0)

    # 参数一：使用python的模型名 （class名称）
    # back_populates ：指定双向关系
    # primaryjoin='BookType.type_id==book_info.type_id'
    # 可以使用backref代替back_populates，BookTypeModel中的relationship删除，backref会自动给外键所在模型添加db.relationship
    # 建议用db.relationship直观点
    file_info = db.relationship('FileInfoModel', back_populates='books')
    book_type = db.relationship('BookTypeModel', backref='books')

    def __repr__(self):
        return json.dumps(self.__to_dict__, ensure_ascii=False)

    @property
    def __to_dict__(self):
        return {
            "id": self.id,
            "bookNo": self.book_no,
            "bookName": self.book_name,
            "bookAuthor": self.book_author,
            "typeId": self.type_id,
            "fileId": self.file_id,
            "createDate": self.create_date,
            "createUser": self.create_user,
            "updateDate": self.update_date,
            "updateUser": self.update_user,
            "version": self.version
        }


class UserModel(db.Model):
    __tablename__ = 'user'
    id = db.Column(db.BigInteger, primary_key=True, autoincrement=True)
    id.__doc__ = '用户id'
    role_id = db.Column(db.BigInteger, nullable=False)
    user_no = db.Column(db.String(50), nullable=False, unique=True)  # 登录工号
    password = db.Column(db.String(255), nullable=False)  # 登录密码
    user_name = db.Column(db.String(100), nullable=False)  # 用户姓名
    email = db.Column(db.String(100), nullable=False)
    phone = db.Column(db.String(45), nullable=False)
    status = db.Column(db.Integer, nullable=False)  # 用户状态 0:正常 1:异常
    create_date = db.Column(db.DateTime, nullable=False, default=datetime.now)
    create_user = db.Column(db.String(255), nullable=False, default='')
    update_date = db.Column(db.DateTime, nullable=False, default=datetime.now)
    update_user = db.Column(db.String(255), nullable=False, default='')
    version = db.Column(db.Integer, nullable=False, default=0)  # 版本号、乐观锁
    user_avatar_id = db.Column(db.BigInteger, nullable=False, default=None)


class RoleModel(db.Model):
    __tablename__ = 'role'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    role_name = db.Column(db.String(32), nullable=False)
    role_code = db.Column(db.String(32), nullable=False)
    create_time = db.Column(db.DateTime, default=datetime.now)
